package org.orz.cloud.redis;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.orz.cloud.redis.persistence.entities.SysRedis;
import org.orz.cloud.redis.persistence.mappers.SysRedisMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 如果没有连接redis，就使用这个工具类，这个工具类只是个mock用的工具类，不建议当生产用。
 */
public class RedisUtil {

    private static final Logger log = LoggerFactory.getLogger(RedisUtil.class);

    private static SysRedisMapper sysRedisMapper;

    private static RedisTemplate<Object, Object> redisTemplate;

    private static boolean mockFlag = false;

    public static void hold(SysRedisMapper redisMapper) {
        sysRedisMapper = redisMapper;
        mockFlag = true;
    }

    public static void setStringRedisTemplate(RedisTemplate template) {
        redisTemplate = template;
    }

    /**
     * 获取值
     */
    public static String get(String key) {
        if (key == null || key.length() == 0) {
            return null;
        }
        log.debug("get info from redis, mock mode is : {}, and the key is : {}", mockFlag, key);
        if(mockFlag){
            SysRedis sysRedis = sysRedisMapper.selectOne(new LambdaQueryWrapper<SysRedis>()
                    .eq(SysRedis::getMockKey, key)
                    .gt(SysRedis::getValidDate, new Date()));
            return sysRedis == null ? null : sysRedis.getMockValue();
        }
        Object value = redisTemplate.opsForValue().get(key);
        return value == null ? null : value.toString();
    }


    /**
     * 保存值
     *
     * @param key   键
     * @param value 值
     */
    public static void set(String key, String value) {
        set(key, value, null);
    }

    /**
     * 保存值
     *
     * @param key             键
     * @param value           值
     * @param expireTimeMills 设置过期时间
     */
    public static void set(String key, String value, Integer expireTimeMills) {
        log.debug("set value into redis, mock mode is : {}, and the key is : {}", mockFlag, key);
        if(mockFlag){
            SysRedis sysRedis = sysRedisMapper.selectOne(new LambdaQueryWrapper<SysRedis>()
                    .eq(SysRedis::getMockKey, key));
            //如果有历史值，就给删除
            if (sysRedis != null) {
                sysRedisMapper.delete(new LambdaQueryWrapper<SysRedis>()
                        .eq(SysRedis::getMockKey, key));
            }
            // 保存到数据库
            SysRedis insert = new SysRedis();
            insert.setMockKey(key);
            insert.setMockValue(value);
            if (expireTimeMills != null) {
                insert.setValidDate(DateUtil.offsetMillisecond(new Date(), expireTimeMills));
            }
            sysRedisMapper.insert(insert);
        } else {
            redisTemplate.opsForValue().set(key, value, expireTimeMills, TimeUnit.MILLISECONDS);
        }
    }

    /**
     * 删除key
     */
    public static void delete(String key){
        if(mockFlag){
            sysRedisMapper.delete(new LambdaQueryWrapper<SysRedis>()
                    .eq(SysRedis::getMockKey, key));
        } else {
            redisTemplate.delete(key);
        }
    }
}
